/**
 * Mark Fedor
 * Tony Greseth
 * CS 5551 User Interface Design
 * Section 1
 * Sai Chittilla
 * Yahtzee Program
 * merry christmas!
 */
package Yahtzee;

import java.util.Arrays;

/**
 * Dice Class contains 5 Die, has accessors and mutators for the Die,
 * and can calculate score values for each category of Yahtzee scoring.
 */
public class Dice {

    /**
     * default constructor 
     */
    public Dice()
    {
        diceArray = new Die[5];
        reset();
    }
    /**
     * constructs and array of 5 die, with the 5 die given in the params
     * used by the client gui to send the die info for processing
     * @param die1 1st die farthest left
     * @param die2 2nd die right from 1
     * @param die3 3rd die right from 2
     * @param die4 4th die right for 3
     * @param die5 5th die farthest right
     */
    public Dice(Die die1, Die die2, Die die3, Die die4, Die die5)
    {
        diceArray = new Die[5];
        diceArray[0] = die1;
        diceArray[1] = die2;
        diceArray[2] = die3;
        diceArray[3] = die4;
        diceArray[4] = die5;
    }
    
    /**
     * copy constructor copies the die values of the argument dice into new dice
     * @param dice set of Dice to be copied
     */
    public Dice(Dice dice)
    {
        for(int i = 0; i < 5; i++)
        this.diceArray[i].setValue(dice.diceArray[i].getValue());
    }

    /**
     * resets the die to the unlocked position 
     */
    public void reset()
    {
        for (int i = 0; i < 5; i++)
        {
            unlockDie(i);
        }
    }

     public Die getDie(int dieIndex)
     {
         return diceArray[dieIndex];
     }
    /**
     * locks the die determined by the dieIndex
     * @param dieIndex index of dieArray to be locked
     */

    public void lockDie(int dieIndex)
    {
        diceArray[dieIndex].setLocked(true);
    }

    /**
     * unlocks the die determined by the dieIndex
     * @param dieIndex index of dieArray to be unlocked
     */
    public void unlockDie(int dieIndex)
    {
        diceArray[dieIndex].setLocked(false);
    }

    /**
     * returns whether die in dieArray is locked
     * @param dieIndex index of dieArray to be unlocked
     */
    public boolean isDieLocked(int dieIndex)
    {
        return diceArray[dieIndex].isLocked();
    }

    /**
     * calls Die.roll on each die in dieArray
     * randomly generates int 1-6 for each unlocked die
     */
    public void rollDice()
    {
        for (int i = 0; i < 5; i++)
        {
            if (diceArray[i].isLocked() == false)
            {
                diceArray[i].roll();
            }
        }
    }

    /**
     * determines score of dice if scored as a three of a kind
     * @return sum of dice if there is a three of a kind otherwise returns 0
     */
    public static int getThreeOfAKind()
    {
        int sum = 0;

        boolean threeOfAKind = false;
        // compares the die determines if three or more are the same
        for (int i = 1; i <= 6; i++)
        {
            int count = 0;
            for (int j = 0; j < 5; j++)
            {
                if (diceArray[j].getValue() == i)
                    count++;
                if (count > 2)
                    threeOfAKind = true;
            }
        }
        // if at least three die are the same calculate the total count
        if (threeOfAKind)
        {
            for (int k = 0; k < 5; k++)
            {
                sum += diceArray[k].getValue();
            }
        }
        return sum;
    }

    /**
     * determines score of dice if scored as a four of a kind
     * @return sum of dice if there is a four of a kind otherwise returns 0
     */
    public static int getFourOfAKind()
    {
        int sum = 0;
        boolean fourOfAKind = false;
        for (int i = 1; i <= 6; i++)
        {
            int count = 0;
            for (int j = 0; j < 5; j++)
            {
                if (diceArray[j].getValue() == i)
                    count++;
                if (count > 3)
                    fourOfAKind = true;
            }
        }
        if (fourOfAKind)
        {
            for (int k = 0; k < 5; k++)
            {
                sum += diceArray[k].getValue();
            }
        }
        return sum;
    }

    /**
     * determines score of dice if scored as a small straight
     * @return 30 if there is a small straight, otherwise returns 0
     */
    public static int getSmallStraight()
   {
    int sum = 0;

  int[] i = new int[5];

  i[0] = diceArray[0].getValue();
  i[1] = diceArray[1].getValue();
  i[2] = diceArray[2].getValue();
  i[3] = diceArray[3].getValue();
  i[4] = diceArray[4].getValue();

  Arrays.sort(i);


  for( int j = 0; j < 4; j++ )
  {
    int temp = 0;
    if( i[j] == i[j+1] )
    {
      temp = i[j];

      for( int k = j; k < 4; k++ )
      {
        i[k] = i[k+1];
      }

      i[4] = temp;
    }
  }

  if( ((i[0] == 1) && (i[1] == 2) && (i[2] == 3) && (i[3] == 4)) ||
      ((i[0] == 2) && (i[1] == 3) && (i[2] == 4) && (i[3] == 5)) ||
      ((i[0] == 3) && (i[1] == 4) && (i[2] == 5) && (i[3] == 6)) ||
      ((i[1] == 1) && (i[2] == 2) && (i[3] == 3) && (i[4] == 4)) ||
      ((i[1] == 2) && (i[2] == 3) && (i[3] == 4) && (i[4] == 5)) ||
      ((i[1] == 3) && (i[2] == 4) && (i[3] == 5) && (i[4] == 6)) )
  {
    sum = 30;
  }

  return sum;
}

    /**
     * determines score of dice if scored as a large straight
     * @return 40 if there is a large straight, else returns 0
     */
    public static int getLargeStraight()
    {
        int sum = 0;

        int[] i = new int[5];

        i[0] = diceArray[0].getValue();
        i[1] = diceArray[1].getValue();
        i[2] = diceArray[2].getValue();
        i[3] = diceArray[3].getValue();
        i[4] = diceArray[4].getValue();

        Arrays.sort(i);
        if( ((i[0] == 1) &&
             (i[1] == 2) &&
             (i[2] == 3) &&
             (i[3] == 4) &&
             (i[4] == 5)) ||
             ((i[0] == 2) &&
             (i[1] == 3) &&
             (i[2] == 4) &&
             (i[3] == 5) &&
             (i[4] == 6)) )
        {
            sum = 40;
        }

        return sum;
    }

    /**
     * determines score of dice if scored as a full house
     * @return 25 if there is a full house, else returns 0
     */
    public static int getFullHouse()
    {
        int sum = 0;
        int threeOfAKindValue = 0;
       
        boolean threeOfAKind = false;
        boolean twoOfAKind = false;
        boolean isFullHouse = false;
        if(isYahtzee())
            return 25;
        for( int i = 1; i <= 6; i++ )
        {
            int dieValue = 0;
            int count = 0;
            for( int j = 0; j < 5; j++ )
            {
                if (diceArray[j].getValue() == i)
                    count++;
                if (count > 2)
                {
                    threeOfAKind = true;
                    threeOfAKindValue = diceArray[j].getValue();
                    count = 0;
                }
            }
        }
        for( int i = 1; i <= 6; i++ )
        {
            int dieValue = 0;
            int count = 0;
            for (int j = 0; j < 5; j++)
            {
                if (i != threeOfAKindValue)
                {
                    if (diceArray[j].getValue() == i)
                        count++;
                    if (count > 1)
                    {
                        twoOfAKind = true;
                    }
                }
            }
        }
        if (threeOfAKind && twoOfAKind)
            return 25;
        else
            return 0;
    }
    /**
     * determines score of dice if scored as a Yahtzee
     * @return 50 if there is a yahtzee, else returns 0
     */
    public static int getYahtzee()
    {
        if(isYahtzee())
            return 50;
        
        else
            return 0;
    }

     /** determines score of dice if scored as chance
     * @return the sum of the dice
     */
    public static int getChance()
    {
        int dice1 = diceArray[0].getValue();
        int dice2 = diceArray[1].getValue();
        int dice3 = diceArray[2].getValue();
        int dice4 = diceArray[3].getValue();
        int dice5 = diceArray[4].getValue();
        int sum = 0;
        sum = dice1 + dice2 + dice3 + dice4 + dice5;
        return sum;
    }

    /**
     * checks to see if yahtzee exists
     * @return true if there is a yahtzee, else false
     */
    public static boolean isYahtzee()
    {
        int dice1 = diceArray[0].getValue();
        int dice2 = diceArray[1].getValue();
        int dice3 = diceArray[2].getValue();
        int dice4 = diceArray[3].getValue();
        int dice5 = diceArray[4].getValue();

        if (dice1 == dice2 && dice1 == dice3 && dice1 == dice4 && dice1 == dice5)
        {
            return true;
        }
        else
            return false;
    }

    /**
     * sums all of the dice with a value of one
     * @return returns sum of ones
     */
    public static int getOnes()
    {
        int dice1 = diceArray[0].getValue();
        int dice2 = diceArray[1].getValue();
        int dice3 = diceArray[2].getValue();
        int dice4 = diceArray[3].getValue();
        int dice5 = diceArray[4].getValue(); 
        int sum = 0;
        if (dice1 == 1)
            sum += dice1;
        if (dice2 == 1)
            sum += dice2;
        if (dice3 == 1)
            sum += dice3;
        if (dice4 == 1)
            sum += dice4;
        if (dice5 == 1)
            sum += dice5;
        return sum;
    }

    /**
     * sums all of the dice with a value of two
     * @return returns sum of twos
     */
    public static int getTwos()
    {
        int dice1 = diceArray[0].getValue();
        int dice2 = diceArray[1].getValue();
        int dice3 = diceArray[2].getValue();
        int dice4 = diceArray[3].getValue();
        int dice5 = diceArray[4].getValue();
        int sum = 0;
        if (dice1 == 2)
            sum += dice1;
        if (dice2 == 2)
            sum += dice2;
        if (dice3 == 2)
            sum += dice3;
        if (dice4 == 2)
            sum += dice4;
        if (dice5 == 2)
            sum += dice5;
        return sum;
    }

    /**
     * sums all of the dice with a value of three
     * @return returns sum of threes
     */
    public static int getThrees()
    {
        int dice1 = diceArray[0].getValue();
        int dice2 = diceArray[1].getValue();
        int dice3 = diceArray[2].getValue();
        int dice4 = diceArray[3].getValue();
        int dice5 = diceArray[4].getValue();
        int sum = 0;
        if (dice1 == 3)
            sum += dice1;
        if (dice2 == 3)
            sum += dice2;
        if (dice3 == 3)
            sum += dice3;
        if (dice4 == 3)
            sum += dice4;
        if (dice5 == 3)
            sum += dice5;
        return sum;
    }

    /**
     * sums all of the dice with a value of four
     * @return returns sum of fours
     */
    public static int getFours()
    {
        int dice1 = diceArray[0].getValue();
        int dice2 = diceArray[1].getValue();
        int dice3 = diceArray[2].getValue();
        int dice4 = diceArray[3].getValue();
        int dice5 = diceArray[4].getValue();
        int sum = 0;
        if (dice1 == 4)
            sum += dice1;
        if (dice2 == 4)
            sum += dice2;
        if (dice3 == 4)
            sum += dice3;
        if (dice4 == 4)
            sum += dice4;
        if (dice5 == 4)
            sum += dice5;
        return sum;
    }

    /**
     * sums all of the dice with a value of five
     * @return returns sum of fives
     */
    public static int getFives()
    {
        int dice1 = diceArray[0].getValue();
        int dice2 = diceArray[1].getValue();
        int dice3 = diceArray[2].getValue();
        int dice4 = diceArray[3].getValue();
        int dice5 = diceArray[4].getValue();
        int sum = 0;
        if (dice1 == 5)
            sum += dice1;
        if (dice2 == 5)
            sum += dice2;
        if (dice3 == 5)
            sum += dice3;
        if (dice4 == 5)
            sum += dice4;
        if (dice5 == 5)
            sum += dice5;
        return sum;
    }

    /**
     * sums all of the dice with a value of six
     * @return returns sum of sixes
     */
    public static int getSixes()
    {
        int dice1 = diceArray[0].getValue();
        int dice2 = diceArray[1].getValue();
        int dice3 = diceArray[2].getValue();
        int dice4 = diceArray[3].getValue();
        int dice5 = diceArray[4].getValue();
        int sum = 0;
        if (dice1 == 6)
            sum += dice1;
        if (dice2 == 6)
            sum += dice2;
        if (dice3 == 6)
            sum += dice3;
        if (dice4 == 6)
            sum += dice4;
        if (dice5 == 6)
            sum += dice5;
        return sum;
    }
    
    private static Die[] diceArray;
}
